home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: netcom.com!marnold
- From: marnold@netcom.com (Matt Arnold)
- Subject: Re: "Deep" Destructor Query
- Message-ID: <marnoldDo19rI.n0A@netcom.com>
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
- References: <826257180snz@pbutler.demon.co.uk>
- Date: Sun, 10 Mar 1996 03:59:42 GMT
- Sender: marnold@netcom20.netcom.com
-
- Peter Hugh Butler <Peter@pbutler.demon.co.uk> writes:
-
- >I have two questions, hope nobody minds. Please answer by e-mail, unless
- >you think that the group would benefit from the answer.
-
- >I have read the FAQ on this subject, but I am still a little confused.
- >(By the way, I know I should use a dynamic multi-dimensional array, but I
- >just wanted to try it this way).
-
- >Destructors
-
- >I have two classes, one instantiated in the other. One (shape) contains a
- >dynamic array of structs, the other (object) contains a dynamic array of
- >shapes. Declared sort of like this:
-
- >struct point
- >{
- >int x, y, z;
- >};
-
- >Class Shape
- >{
- >private:
- >point *p; //dynamic array of points
- >//...etc
- >};
-
- >Class Object
- >{
- >private:
- >int numshapes; //number of data elements
- >shape *shapes; //dynamic array of shapes
- >//etc...
- >};
-
- >Now, this all works quite well, apart from when it comes to destructor
- >functions. For shape I have:
-
- >Shape::~Shape()
- >{
- >if (p)
- > delete [] p;
- >}
-
- >which works ok. But when I wrote a destructor for Object, like this:
-
- >Object::~Object()
- >{
- >for (int i = 0; i < numshapes; i++)
- > shapes[i].~shape(); //"Deep" destructor, deletes underlying arrays.
-
- >delete [] shapes; //delete the array of pointers
- >}
-
- This is wrong, you don't have an array of pointers to shape objects, you
- have an array of shape objects (got back and look at your declaration for
- the shapes member).
-
- It should be...
-
- shape **shapes;
-
- ...instead of...
-
- shape *shapes;
-
- ...(note the extra asterisk).
-
- In your code, as it is, when you do "delete [] shapes" you are asking the
- compiler to generate code that deletes an array of shape *objects*, not
- pointers to shape objects. Since your array is not an array of shape
- objects themselves, just pointers to them, this generated code dies a
- horrible GPF death, as it tries to treat a chunk of memory as an array of
- shape objects and call shape::~shape() for each element.
-
- >The program causes a General Protection Fault (guess which OS I'm using and
- >win a cookie). It fails when it tries to delete the array of null pointers
- >pointed to by shape. It works when I leave the "delete [] shapes;" line out.
-
- >Well, I have two questions:
-
- >1) If I simply "delete [] shapes" with no loop to delete the arrays underneath,
- > will the ~shape() destructor be automatically called, thus deleting the
- > shape objects correctly? I wouldn't think so, but it would be good to be
- > corrected.
-
- No, it won't. But, as I've already explained, you code has a big mistake in
- it, so your starting assumptions are a little off.
-
-
- Rewrite Object like this...
-
-
- Class Object
- {
- private:
- int numshapes; //number of data elements
- shape **shapes; //dynamic array of shape POINTERS!!
- //etc...
- };
-
- Object::~Object()
- {
- for (int i = 0; i < numshapes; i++)
- shapes[i]->~shape(); // destroy via POINTER
- delete [] shapes; //delete the array of POINTERS
- }
-
- ..and things should start working.
-
- >2) If I delete each shape with a loop (as above), does this mean that shapes
- > pointer points to nothing? I would have thought that it would point to
- > an array of null pointers.
-
- No. Well, first you didn't have an array of pointers, but I hope you see
- your mistake now.
-
- To answer you question in general, deleting an object pointed to by some
- pointer variable DOES NOTHING to the pointer variable itself (pointers
- are no automatically nulled-out by delete).
-
- shape* p = new shape();
-
- // here, p contains the value of some address
-
- delete p;
-
- // here, p still contains the same address, not null, even though the
- // shape it pointed to has been destroyed.....yes, p certainly contains
- // an invalid address, but not null
-
- The same goes for an array of shape pointers. Just because you delete
- each shape in it, doesn't make each array element null. The array is
- still full of pointer values, all of them now invalid.
-
-
- A final note, if you are doing a lot of work with dynamic arrays, you
- might want to look into using the Standard Template Library (STL). It
- contains a nice template class called vector, which acts like a normal
- array, but can resize itself dynamically. The STL vector class is
- already coded, tested and ready for you to use.
-
-
- Regards,
- -------------------------------------------------------------------------
- Matt Arnold | | ||| | |||| | | | || ||
- marnold@netcom.com | | ||| | |||| | | | || ||
- Boston, MA | 0 | ||| | |||| | | | || ||
- 617.389.7384 (h) 617.576.2760 (w) | | ||| | |||| | | | || ||
- C++, MIDI, Win32/95 developer | | ||| 4 3 1 0 8 3 || ||
- -------------------------------------------------------------------------
-